import { Component, isValid } from "cc";
import { noop } from "./ViewCompilerType";


export function BindComponentString(ctype: typeof Component){
    return {
        component: ctype,
        binder: function (vm: any, attr: string, component: Component, hasSetter: boolean) {
            return _BindComponentString(ctype, vm, attr, component, hasSetter);
        }
    }
}

function _BindComponentString(ctype: typeof Component, vm: any, attr: string, component: Component, hasSetter: boolean) {
    let unwatch = noop;
    let watchOptions = {
        // user: true,
        sync: true,
        immediate: true,
    }
    if (!isValid(component)) {
        return unwatch;
    }

    if (component instanceof ctype) {
        let node = component.node;
        // // element 值初始化
        // component.string = vm[attr];

        //扩展，string 值改变时触发 binder-text-changed 消息以实现双向数据绑定
        let comp = component as any;
        if (typeof comp['_string_backup'] == 'undefined') {
            comp['_string_backup'] = "";
            Object.defineProperty(comp, "_string", {
                get() {
                    return this['_string_backup'];
                },
                set(value) {
                    this['_string_backup'] = value;
                    node.emit('binder-text-changed', component);
                },
                enumerable: true,
                configurable: true
            });
        }

        // element->model 数据绑定
        node.on('binder-text-changed', (e: any) => {
            if(hasSetter){
                //@ts-ignore
                vm[attr] = component.string;
            }
        })

        // model->element 数据绑定
        unwatch = vm.$watch(attr, (value: any, oldValue: any) => {
            if (!isValid(component)) {
                unwatch?.();
                return;
            }

            //@ts-ignore
            component.string = value;
        }, watchOptions)
    }
    
    return unwatch;
}